﻿#region - Class details -
/*  
 *  Developer   : Wicus Botha
 *  Description : 
 *  History     : WB - 2009-12-0 - Created
 */
#endregion

using System;
using System.Data;
using System.Windows.Forms;
using IQ.BaseWindows;
using IQ.DbBase;

namespace IQ.WinComponents
{
    public class grdFilter : DataGridView
    {
        #region # Constructor #
        public grdFilter()
        {
            this.AllowUserToAddRows = false;
            this.AllowUserToDeleteRows = false;
            this.ReadOnly = true;
            this.CellEnter += new System.Windows.Forms.DataGridViewCellEventHandler(this.grd_CellEnter);
            this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.grd_KeyPress);
            this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.grd_MouseUp);
            this.DataSourceChanged += new System.EventHandler(this.setSourceView);
            this.ColumnHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.grd_ColumnHeaderMouseClick);
        }
        #endregion

        #region - Private variables -
        private Label filterValueLabel = null;
        private TextBox txtFilter = null;
        private bool filterValueAny = false;
        #endregion

        #region - Private methods -
        private void setSourceView(object sender, EventArgs e)
        {
            sourceView = null;
            DataTable sourceData = this.DataSource as DataTable;
            if (sourceData != null)
                sourceView = sourceData.DefaultView;
            else
                sourceView = this.DataSource as DataView;
        }
        private void setDefaultSelectedColumn()
        {
            if (this.FirstDisplayedCell != null)
                setSelectedColumn(this.FirstDisplayedCell.ColumnIndex);
            else
                setSelectedColumn(0);
        }
        private void setSelectedColumn(int columnIndex)
        {
            selectedCol = columnIndex;
            selectedColName = this.Columns[selectedCol].Name;
            selectedField = this.Columns[selectedCol].DataPropertyName;
            if (selectedFieldLabel != null)
                selectedFieldLabel.Text = this.Columns[selectedCol].HeaderText;
        }
        protected virtual bool checkIllegalChar(char key)
        {
            // Skip "Escape & Tab"
            if (key == 27 || key == '\t')
                return true;
            else // Check char
            {
                if (key == '*' || key == '[' || key == ']')
                {
                    General.MesDlg("Invalid search character.", 'E');
                    return true;
                }
                else
                    return false;
            }
        }
        private void emptyFilter()
        {
            if (String.IsNullOrEmpty(fixFilterValue))
                sourceView.RowFilter = "";
            else
                sourceView.RowFilter = fixFilterValue;
        }
        private void filterData()
        {
            inProcess = true;            
            if (sourceView != null)
            {
                if (filterValue.Length > 0)
                {
                    if (String.IsNullOrEmpty(selectedField))
                        setDefaultSelectedColumn();
                    if (IsFilterValid(filterValue))
                    {
                        string filterVal;
                        if (sourceView.Table.Columns[selectedField].DataType == typeof(System.DateTime))
                            filterVal = DbUtil.GetFilterValueDateBetween(selectedField,filterValue.Replace("'", "''"));
                        else
                            filterVal = DbUtil.GetFilterValue(sourceView.Table.Columns[selectedField].DataType.ToString(), filterValue.Replace("'", "''"), filterValueAny);
                        //
                        if (filterVal.Length > 0)
                        {
                            if (String.IsNullOrEmpty(fixFilterValue))
                                sourceView.RowFilter = selectedField + " " + filterVal;
                            else
                                sourceView.RowFilter = fixFilterValue + " " + fixFilterOperator + " " + selectedField + " " + filterVal;
                        }
                        else
                            emptyFilter();
                    }
                }
                else
                {
                    emptyFilter();
                }
                this.SetCellAfterFilter();
                // this is the same as filter
                //bindSource.Position = bindSource.Find(selectedField, txtFilter.Text);
            }
            inProcess = false;
        }
        private void updateFilterValue()
        {
            if (txtFilter != null)
            {
                txtFilter.Text = filterValue;
                // Filter will run by itself
            }
            else
            {
                if (filterValueLabel != null)
                    filterValueLabel.Text = filterValue;
                filterData();
            }
        }
        private bool verifyLabels()
        {
            if ((filterValueLabel != null) && (selectedFieldLabel != null)
                && (filterValueLabel == selectedFieldLabel))
            {
                General.MesDlg("Filter label & Field label cannot be the same label", 'E');
                return false;
            }
            else
                return true;

        }
        // ---------------------------------
        // -- Events
        // ---------------------------------
        private void grd_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            setSelectedColumn(e.ColumnIndex);
            SetCurrentCell(e.ColumnIndex);
        }
        private void grd_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            if ((!inProcess) && (this.Focused && e.RowIndex >= 0 && e.ColumnIndex >= 0))
            {
                setSelectedColumn(e.ColumnIndex);
            }
        }
        private void grd_KeyPress(object sender, KeyPressEventArgs e)
        {
            if ((Control.ModifierKeys & Keys.Control) == 0)
            {
                if ((e.KeyChar == (char)Keys.Back) ||
                    (e.KeyChar == (char)Keys.Delete))
                {
                    if (filterValue.Length > 0)
                        filterValue = filterValue.Remove(filterValue.Length - 1);
                }
                else
                {
                    if (!checkIllegalChar(e.KeyChar))
                        filterValue += e.KeyChar;
                }
                //
                updateFilterValue();
            }
        }
        private void txtFilter_TextChanged(object sender, EventArgs e)
        {
            filterValue = txtFilter.Text;
            if (filterValueLabel != null)
                filterValueLabel.Text = filterValue;
            filterData();
        }
        protected virtual void txtFilter_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = checkIllegalChar(e.KeyChar);
        }

        private void attachFilterBoxEvents()
        {
            this.txtFilter.TextChanged += new System.EventHandler(this.txtFilter_TextChanged);
            this.txtFilter.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtFilter_KeyPress);
        }
        private void detachFilterBoxEvents()
        {
            this.txtFilter.TextChanged -= new System.EventHandler(this.txtFilter_TextChanged);
            this.txtFilter.KeyPress -= new System.Windows.Forms.KeyPressEventHandler(this.txtFilter_KeyPress);
        }
        /// <summary>
        /// Toggle Include / Exclude header text on single select copy
        /// </summary>
        /// <param name="sender">This grid</param>
        /// <param name="e">Event params</param>
        private void grd_MouseUp(object sender, MouseEventArgs e)
        {
            if (this.SelectedCells.Count > 1)
                this.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
            else
                this.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
        }

        #endregion

        #region - Protected variables -
        protected string selectedField = "";
        protected string selectedColName = "";
        protected string filterValue = "";
        protected string fixFilterValue = "";
        protected string fixFilterOperator = "AND";
        protected int selectedCol = 0;
        protected Label selectedFieldLabel = null;
        private bool inProcess = false;
        protected DataView sourceView = null;
        #endregion

        #region - Public properties / variables -
        public string SelectedField
        {
            get { return selectedField; }
        }
        public Label SelectedFieldLabel
        {
            get { return selectedFieldLabel; }
            set
            {
                selectedFieldLabel = value;
                if (!verifyLabels())
                    selectedFieldLabel = null;
            }
        }
        public bool FilterValueAny
        {
            get { return filterValueAny; }
            set { filterValueAny = value; }
        }
        public Label FilterValueLabel
        {
            get { return filterValueLabel; }
            set
            {
                filterValueLabel = value;
                if (!verifyLabels())
                    filterValueLabel = null;
            }
        }
        public string FixFilterValue
        {
            get { return fixFilterValue; }
            set { fixFilterValue = value; }
        }
        public string FixFilterOperator
        {
            get { return fixFilterOperator; }
            set { fixFilterOperator = value; }
        }
        public int SelectedCol
        {
            get { return selectedCol; }
        }
        public TextBox TxtFilter
        {
            get { return txtFilter; }
            set
            {   // Clear previous events
                if (txtFilter != null)
                {
                    detachFilterBoxEvents();
                }
                txtFilter = value;
                if (txtFilter != null)
                {
                    attachFilterBoxEvents();
                }
            }
        }
        public bool InProcess
        {
            get { return inProcess; }
            set { inProcess = value; }
        }
        #endregion

        #region - Public methods -
        public bool IsFilterValid(string searchValue)
        {
            if (this != null)
            {
                DataGridViewColumn col = this.Columns[selectedColName];
                if (col != null && col.ValueType != null)
                    return DbUtil.CheckTypeAndValue(col.ValueType.ToString(), searchValue);
                else
                    return false;
            }
            else
                return true;
        }
        public void SetCurrentCell(int colIndex)
        {
            if (this.Rows.Count > 0)
            {
                if (this.Columns[colIndex].Visible)
                    this.CurrentCell = this.Rows[0].Cells[colIndex];
                else if (this.Rows[0].Cells[0].Visible)
                {
                    this.CurrentCell = this.Rows[0].Cells[0];
                }
            }
        }
        public void SetCellAfterFilter()
        {
            SetCurrentCell(selectedCol);
        }
        public void SetCurrentFilter(int columnIndex, string filterValue)
        {
            setSelectedColumn(columnIndex);
            this.TxtFilter.Text = filterValue;
        }
        public void RunFilterData()
        {
            updateFilterValue();
        }
        public void FixFilterChanged()
        {
            filterData();
        }
        #endregion
    }
}
